﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Linq.Expressions;

namespace Reporting.Infrastructure
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class, new()
    {
        /// <summary>
        /// 上下文对象
        /// </summary>
        private readonly ReportingDbContext dbcontext;

        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger<BaseRepository<T>> _logger;

        public BaseRepository(ILogger<BaseRepository<T>> logger, ReportingDbContext dbcontext)
        {
            _logger = logger;
            this.dbcontext = dbcontext;
        }

        /// <summary>
        /// 查询全部数据
        /// </summary>
        /// <returns></returns>
        public async Task<IList<T>> GetAllAsync()
        {
            try
            {
                return await dbcontext.Set<T>().ToListAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError("查询失败" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 根据条件查询所有信息
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public async Task<IList<T>> GetAllAsync(Expression<Func<T, bool>> where)
        {
            try
            {
                return await dbcontext.Set<T>().Where(where).ToListAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError("查询失败" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 根据条件查询单个信息
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>符合条件的实体，如果未找到则返回 null</returns>
        public async Task<T?> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
        {
            try
            {
                return await dbcontext.Set<T>().FirstOrDefaultAsync(predicate, cancellationToken);
            }
            catch (Exception ex)
            {
                // 记录详细的异常信息
                _logger.LogError(ex, "查询失败：条件 {Predicate}, 实体类型 {EntityType}", predicate, typeof(T).Name);
                throw new ApplicationException("查询数据时发生错误，请稍后重试", ex);
            }
        }

        /// <summary>
        /// 新增数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> InsertAsync(T entity)
        {
            try
            {
                await dbcontext.Set<T>().AddAsync(entity);
                return await dbcontext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError("新增失败" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 更新
        /// </summary   >
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> UpdateAsync(T entity)
        {
            try
            {
                dbcontext.Set<T>().Update(entity);
                return await dbcontext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError("更新失败" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 批量更新数据
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public Task<int> UpdateRangeAsync(IList<T> entities)
        {
            try
            {
                dbcontext.Set<T>().UpdateRange(entities);
                return dbcontext.SaveChangesAsync();
            }
            catch (Exception e)
            {
                _logger.LogError("更新失败" + e.Message);
                throw;
            }
        }

        /// <summary>
        /// 批量新增数据
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public Task<int> InsertRangeAsync(IList<T> entities)
        {
            try
            {
                dbcontext.Set<T>().AddRange(entities);
                return dbcontext.SaveChangesAsync();
            }
            catch (Exception e)
            {
                _logger.LogError("新增失败" + e.Message);
                throw;
            }
        }
        /// <summary>
        /// 删除单个实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsync(T entity)
        {
            try
            {
                dbcontext.Set<T>().Remove(entity);
                return await dbcontext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError("删除失败" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public Task<int> DeleteRangeAsync(IList<T> entities)
        {
            try
            {
                dbcontext.Set<T>().RemoveRange(entities);
                return dbcontext.SaveChangesAsync();
            }
            catch (Exception e)
            {
                _logger.LogError("批量删除失败" + e.Message);
                throw;
            }
        }
    }
}
